<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <Header
          @addTodo="addTodo"
      />
      <List
          :todoList="todoList"
          :changeChecked="changeChecked"
          :deleteTodo="deleteTodo"
      />
      <Footer
          :todoList="todoList"
          @changeAllTodo="changeAllTodo"
          @delFinished="delFinished"
          :key="footerKey"
      />
    </div>
  </div>
</template>
<script lang="ts" >
import {defineComponent} from "vue";
import Header from "@/components/Header/index.vue";
import List from "@/components/List/index.vue";
import Footer from "@/components/Footer/index.vue";
export default defineComponent({
  name:'App',
  components:{
    Header,
    List,
    Footer
  }
})
</script>
<script setup lang="ts">
//引入nanoid 用来生成id
import {nanoid} from "nanoid";
import {todoListType} from '@/types/todoList'
import {watch, ref, onMounted} from "vue";
import {getTodoList, saveTodoList} from '@/utils/localStorage'
//初始定义任务数据todoList
// const todoList = ref<todoListType>([
//     {id:nanoid(),thing:'吃饭',done:false},
//     {id:nanoid(),thing:'睡觉',done:true},
//     {id:nanoid(),thing:'打豆豆',done:false},
// ])

//定义数据,并在页面初始化后通过本地存储获取数据
const todoList = ref<todoListType>([])
//初始化函数(挂载完成)
onMounted(()=>{
  getTodoList()
})
//改变数据是否被选中状态函数
const changeChecked = (id:string,done:boolean)=>{
  todoList.value.forEach(item =>{
    item.id === id ? item.done = done : '';
  })
}

//添加数据的自定义事件(子传父)
const addTodo = (thing:string)=>todoList.value.push({id:nanoid(),thing,done:false})

//点击删除按钮事件函数
const deleteTodo = (id:string)=> {
  //一定要重新赋值
  todoList.value = todoList.value.filter(item => item.id != id)
}
//全选/全不选自定义事件
const changeAllTodo = (done:boolean)=> todoList.value.forEach(item=>item.done=done)

//定义footer组件key值（根据dff算法，用来改变key值进行组件重新加载）
let footerKey = ref<number>(0)

//清楚已完成任务自定义事件
const delFinished = () =>{
  todoList.value = todoList.value.filter(item => !item.done)
  //用来改变key值进行组件重新加载,更新已完成任务的数据显示
  footerKey.value++
}

//监听数据变化,进行数据永久化存储
//watch 三个参数  1.监听的数据可以是数据,也可以写个函数,return出一个数据
//              2.回调函数        3.配置对象
//第一个参数 监听的是.value时,只会监听内部数据的状态变化
//第一个参数 监听的不是.value时,只会监听数据的数量变化
//所以最好的方法就是  监听原始数据 + deep:true  的配置
// watch(todoList,(newVal,oldVal)=>{
//   saveTodoList(newVal)
// },{deep:true})
//简写:
watch(todoList,saveTodoList,{deep:true})
</script>

<style scoped>
body {
  background: #fff;
}

.btn {
  display: inline-block;
  padding: 4px 12px;
  margin-bottom: 0;
  font-size: 14px;
  line-height: 20px;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
  0 1px 2px rgba(0, 0, 0, 0.05);
  border-radius: 4px;
}

.btn-danger {
  color: #fff;
  background-color: #da4f49;
  border: 1px solid #bd362f;
}

.btn-danger:hover {
  color: #fff;
  background-color: #bd362f;
}

.btn:focus {
  outline: none;
}

.todo-container {
  width: 600px;
  margin: 0 auto;
}
.todo-container .todo-wrap {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}
</style>
